﻿// -----------------------------------------------------------------------
// <copyright file="CheckersGameControl.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace B13_Ex02
{
    using System;
    using System.Collections.Generic;
    using System.Text;

    public delegate void AnnounceMessageDelegate(string i_message);

    public delegate void ChangeBoardDelegate(BoardSquare[,] i_BoardSquare);

    public delegate void ScoreUpdateDelegate(PlayerInfo i_Player1, PlayerInfo i_Player2);

    public delegate void DisplayWinnerDelegate(PlayerInfo i_Winner, PlayerInfo i_MaybeWinner);

    public delegate void ShowActivePlayerDelegate(PlayerInfo i_Player1, PlayerInfo i_Player2);

    public delegate void DisableAndEnablePlayersButtonsDelegate(PlayerInfo i_Active, PlayerInfo i_Passive, BoardSquare[,] i_BoardSquare);

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public enum eGameTypeSelection
    {
        PlayerVsPlayer = 1,
        PlayerVsComputer = 2
    }

    public enum eStartNewGame
    {
        Yes = 1,
        No = 2
    }

    public enum ePlayerDirection
    {
        PositiveDirection = 1,
        NegativeDirection = -1
    }

    public class CheckersGameControl
    {
        private readonly PlayerInfo m_Player1 = new PlayerInfo(GamePiece.WhitePiece, GamePiece.WhitePieceKing, (int)ePlayerDirection.PositiveDirection, true);
        private readonly PlayerInfo m_Player2 = new PlayerInfo(GamePiece.BlackPiece, GamePiece.BlackPieceKing, (int)ePlayerDirection.NegativeDirection, false);
        private GameBoard m_CheckersGameBoard = new GameBoard();
        private bool m_IsGameOver = false;
        private bool m_LastMoveWasLegal = false;

        public event AnnounceMessageDelegate DisplayMessage;
        
        public event ChangeBoardDelegate ChangedBoard;

        public event ScoreUpdateDelegate UpdatedScore;
        
        public event DisplayWinnerDelegate DisplayedWinner;
        
        public event DisableAndEnablePlayersButtonsDelegate DisabledAndEnabledPlayersButtons;

        public CheckersGameControl(
            AnnounceMessageDelegate i_DisplayMessage,
            ChangeBoardDelegate i_ChangeBoardDeledate,
            ScoreUpdateDelegate i_ScoreUpdateDelegate,
            DisplayWinnerDelegate i_DisplayWinnerDelegate,
            DisableAndEnablePlayersButtonsDelegate i_DisableAndEnablePlayersButtonsDelegate)
        {
            DisplayMessage += i_DisplayMessage;
            ChangedBoard += i_ChangeBoardDeledate;
            DisplayedWinner += i_DisplayWinnerDelegate;
            UpdatedScore += i_ScoreUpdateDelegate;
            DisabledAndEnabledPlayersButtons += i_DisableAndEnablePlayersButtonsDelegate;
        }

        public bool IsGameOver
        {
            get { return m_IsGameOver; }
            set { m_IsGameOver = value; }
        }

        public bool LastMoveWasLegal
        {
            get { return m_LastMoveWasLegal; }
            set { m_LastMoveWasLegal = value; }
        }

        public GameBoard CheckersGameBoard
        {
            get { return m_CheckersGameBoard; }
            set { m_CheckersGameBoard = value; }
        }

        public void RunNewGame()
        {
            m_CheckersGameBoard.InitializeBoard(m_Player1, m_Player2);
            DisabledAndEnabledPlayersButtons.Invoke(m_Player1, m_Player2, m_CheckersGameBoard.GameBoardCurrent);
            ChangedBoard.Invoke(m_CheckersGameBoard.GameBoardCurrent);
            UpdatedScore.Invoke(m_Player1, m_Player2);
        }

        public void RunNewTournament()
        {
            m_Player1.Points = 0;
            m_Player2.Points = 0;
            RunNewGame(); 
        }

        public void RemovePiece(int i_Xposion, int i_Yposition)
        {
            m_CheckersGameBoard.RemovePiece(i_Xposion, i_Yposition);
        }

        public void InitGameSpecification(string i_Player1Name, string i_Player2Name, bool i_HasSecondPlayer, int i_BoardSize)
        {
            m_Player1.PlayerName = i_Player1Name;
            m_Player2.PlayerName = i_Player2Name;

            m_Player2.IsHuman = i_HasSecondPlayer;

            m_CheckersGameBoard = new GameBoard(i_BoardSize);
        }

        public void ResetGameBourd()
        {
            m_CheckersGameBoard.ResetGameBoard();
        }

        public void MoveOfSinglePlayer(int i_XCurrent, int i_YCurrent, int i_XFuture, int i_YFuture)
        {
            if (m_Player1.IsActive)
            {
                MoveActivePlayerAndUpdateActivity(i_XCurrent, i_YCurrent, i_XFuture, i_YFuture, m_Player1, m_Player2);
            }
            else
            {
                MoveActivePlayerAndUpdateActivity(i_XCurrent, i_YCurrent, i_XFuture, i_YFuture, m_Player2, m_Player1);
            }

            DisabledAndEnabledPlayersButtons.Invoke(m_Player1, m_Player2, m_CheckersGameBoard.GameBoardCurrent);
        }

        private void MoveActivePlayerAndUpdateActivity(int i_XCurrent, int i_YCurrent, int i_XFuture, int i_YFuture, PlayerInfo i_ActivePlayer, PlayerInfo i_PassivePlayer)
        {
            i_ActivePlayer.IsActive = false;
            i_PassivePlayer.IsActive = true;
            ChangePlayerPlace(i_ActivePlayer, i_XCurrent, i_YCurrent, i_XFuture, i_YFuture);
            MoveOfSinglePlayer(i_ActivePlayer, i_PassivePlayer);
        }

        public void CheckEndGame()
        {
            if (m_IsGameOver)
            {
                CheckWinner();
            }
        }

        private void ChangePlayerPlace(PlayerInfo i_ActivePlayer, int i_XCurrent, int i_YCurrent, int i_XFuture, int i_YFuture)
        {
            i_ActivePlayer.xCurrent = i_XCurrent;
            i_ActivePlayer.yCurrent = i_YCurrent;
            i_ActivePlayer.xFuture = i_XFuture;
            i_ActivePlayer.yFuture = i_YFuture;
        }

        private void MoveOfSinglePlayer(PlayerInfo i_ActivePlayer, PlayerInfo i_PassivePlayer)
        {
            string messageToUser;
            TurnsManager playerTurn = new TurnsManager(m_CheckersGameBoard, i_ActivePlayer, i_PassivePlayer);
            playerTurn.MakeTurn(m_CheckersGameBoard, i_ActivePlayer, i_PassivePlayer, out messageToUser, out m_IsGameOver, out m_LastMoveWasLegal);

            if (messageToUser != null)
            {
                DisplayMessage.Invoke(messageToUser);
            }

            ChangedBoard.Invoke(m_CheckersGameBoard.GameBoardCurrent);
            DisabledAndEnabledPlayersButtons.Invoke(i_ActivePlayer, i_PassivePlayer, m_CheckersGameBoard.GameBoardCurrent);
            UpdatedScore.Invoke(m_Player1, m_Player2);
        }

        private void CheckWinner()
        {
            if (m_Player1.Points > m_Player2.Points)
            {
                m_Player1.Victories++;
                m_Player1.TotalPoints += (byte)(m_Player1.Points - m_Player2.Points);
                DisplayedWinner.Invoke(m_Player1, null);
            }
            else if (m_Player1.Points < m_Player2.Points)
            {
                m_Player2.Victories++;
                m_Player2.TotalPoints += (byte)(m_Player2.Points - m_Player1.Points);
                DisplayedWinner.Invoke(m_Player2, null);
            }
            else
            {
                DisplayedWinner.Invoke(m_Player2, m_Player1);
            }
        }

        public void ChangePlayersName(string i_NamePlayer1, string i_NamePlayer2)
        {
            m_Player1.PlayerName = i_NamePlayer1;
            m_Player2.PlayerName = i_NamePlayer2;
            UpdatedScore.Invoke(m_Player1, m_Player2);
        }
    }
}
